package perf.data;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public abstract class BaseItem <S extends BaseInterface,P> implements BaseInterface {

	private static final long serialVersionUID = -4174742487617608260L;
	private static final SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss" );
	
	public static final int NOT_FOUND = -1;
	
	private final ArrayList<S> siblings = new ArrayList<S>();
	private final String name;
	private P parent;
	
	public BaseItem( String name ) {
		this.name = name;
	}
	
	public BaseItem( Date date ) {
		this.name = format.format( date );
	}
	
	public String getName( ) {
		return name;
	}
	
	@SuppressWarnings("unchecked")
	public void setParent( BaseItem parent ) {
		this.parent = (P) parent;
	}
	
	public P getParent( ) {
		return parent;
	}
	
	public boolean hasSibling( String siblingName ) {
		return findSibling( siblingName ) != null;
	}
	
	public S findSibling( String siblingName ) {
		for ( S sib : siblings ) {
			if ( sib.getName().equals( siblingName ) ) {
				return sib;
			}
		}
		return null;
	}
	
	public S getSibling( int idx ) {
		return siblings.get( idx );
	}
	
	public S getSibling( String name ) {
		int idx = getSiblingIdx( name );
		
		if ( idx == NOT_FOUND ) {
			throw new RuntimeException( "No sibling of name \"" + name + "\"" );
		}
		
		return getSibling( idx );
	}
	
	public int getSiblingIdx( String siblingName ) {
		for ( int i = 0; i < siblings.size(); i++ ) {
			if ( siblings.get( i ).equals( siblingName ) ) {
				return i;
			}
		}
		return NOT_FOUND;		
	}
	
	protected S add( S sibling ) {
		sibling.setParent( this );
		siblings.add( sibling );
		return sibling;
	}
	
	public List<S> siblings( ) {
		return siblings;
	}
	
	public void compact( ) {
		siblings.trimToSize();
		for ( S sib : siblings ) {
			sib.compact();
		}
	}
	
	public abstract long getCost(int costidx );
}
